package jmine.tec.database.query;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.Callable;

import org.hibernate.jdbc.Work;

/**
 * Loader do mapa de tabelas de um banco.
 * 
 * @author lundberg
 */
public class TableLoader implements Callable<Map<String, Table>> {

    private final Database database;

    /**
     * Construtor
     * 
     * @param database database
     */
    public TableLoader(Database database) {
        this.database = database;
    }

    /**
     * {@inheritDoc}
     */
    public Map<String, Table> call() {
        final Map<String, Table> tables = new TreeMap<String, Table>();
        this.database.doWork(new Work() {
            public void execute(Connection connection) throws SQLException {
                String schema = TableLoader.this.database.getSchema();
                this.find(connection, null, schema, null, "TABLE");
                this.find(connection, null, schema == null ? null : schema.toUpperCase(), "%", "TABLE");
            }

            private void find(Connection connection, String catalog, String schemaPattern, String tableNamePattern, String... types)
                    throws SQLException {
                ResultSet rs = null;
                try {
                    rs = connection.getMetaData().getTables(catalog, schemaPattern, tableNamePattern, types);
                    while (rs.next()) {
                        String tableName = rs.getString("TABLE_NAME");
                        if (!tables.containsKey(tableName)) {
                            tables.put(tableName, new Table(TableLoader.this.database, tableName));
                        }
                    }
                } finally {
                    DatabaseUtil.closeQuietly(rs);
                }
            }
        });
        return tables;
    }
}
